<前端>性能优化
http优化
- 减少单次请求时间
 - 减少请求次数
 
webpack优化
- 提高构建速度
 
- bable-loader中使用 include 或 exclude 来帮我们避免不必要的转译,比如排除node_modules文件夹
 
- 使用DLLPlugin打包第三方库
 - Happypack将 loader 由单进程转为多进程
 - 使用tree-shaking删除冗余代码,UglifyJsPlugin
 - webpack按需加载
 - 使用CommonsChunkPlugin拆分公共代码,webpack4使用optimization.splitChunks
 
- https://crazyaguai.github.io/2019/01/15/webpack-CommonsChunkPlugin%E4%B8%8Eoptimization-splitChunks/
 
- 生产环境关闭source-map
 - 压缩混淆代码,UglifyJsPlugin
 - 长缓存优化
 
- html-webpack-inline-chunk-plugin提前加载manifest.js
 
服务器开启gzip
图片优化
- 一个像素对应的二进制位数越多,它可以表示的颜色种类就越多,成像效果也就越细腻,文件体积相应也会越大。一个二进制位表示两种颜色(0|1 对应黑|白),如果一种图片格式对应的二进制位数有 n 个,那么它就可以呈现 2^n 种颜色。
 
- JPEG/JPG:有损压缩、体积小、加载快、不支持透明
 
- 优点:有损压缩,即使被称为“有损”压缩,JPG的压缩方式仍然是一种高质量的压缩方式:当我们把图片体积压缩至原有体积的 50% 以下时,JPG 仍然可以保持住 60% 的品质。
 - 使用场景:JPG 适用于呈现色彩丰富的图片,在我们日常开发中,JPG图片经常作为大的背景图、轮播图或 Banner 图出现。
 - 缺点:处理矢量图形和 Logo等线条感较强、颜色对比强烈的图像时,人为压缩导致的图片模糊会相当明显。JPEG 图像不支持透明度处理。
 
- PNG-8 与 PNG-24:无损压缩、质量高、体积大、支持透明
 
- 使用场景:呈现小的 Logo、颜色简单且对比强烈的图片或背景等。
 
- SVG:文本文件、体积小、不失真、兼容性好
 
- 特性:SVG 与 PNG 和 JPG 相比,文件体积更小,可压缩性更强。图片可无限放大而不失真。SVG 是文本文件,可以直接写在html dom中。
 - 局限:渲染成本比较高,有学习成本(是可编程的)。
 - 使用场景:
 
- base64:文本文件、依赖编码、小图标解决方案
 
- Base64 是一种用于传输 8Bit 字节码的编码方式,通过对图片进行 Base64 编码,我们可以直接将编码结果写入 HTML 或者写入 CSS,从而减少 HTTP 请求的次数。
 - 应用场景:小图标,更新频率非常低
 - url-loader可配置转换为base64图
 
- WebP
 
- Google 专为 Web 开发的一种旨在加快图片加载速度的图片格式,它支持有损压缩和无损压缩。
 - WebP 像 JPEG 一样对细节丰富的图片信手拈来,像 PNG 一样支持透明,像 GIF 一样可以显示动态图片——它集多种图片文件格式的优点于一身。
 - 局限性:浏览器支持情况不好,增加服务器的负担(编码同样质量的WebP文件会占用更多的计算资源。)
 
浏览器缓存
- Memory Cache
 
- 指内存中的缓存,从优先级上来说,它是浏览器最先尝试去命中的一种缓存。从效率上来说,它是响应速度最快的一种缓存。
 - Base64 格式的图片,几乎永远可以被塞进 memory cache,体积不大的 JS、CSS文件,也有较大地被写入内存的几率。
 
- Service Worker Cache
 
- Service Worker 是一种独立于主线程之外的 Javascript 线程。
 - https://www.jianshu.com/p/62338c038c42
 
- HTTP Cache
 
- Push Cache
 
- Push Cache 是指 HTTP2 在 server push 阶段存在的缓存。
 
本地存储
- cookie
 
- 劣势:有体积上限(4KB),紧跟域名,会带来资源浪费,同一个域名下的所有请求,都会携带 Cookie。
 
- web storage
 
- 特性:存储容量大,仅位于浏览器端,不与服务端发生通信。
 - Local Storage 与 Session Storage 的区别:生命周期,Local Storage 是持久化的本地存储,Session Storage 是临时性的本地存储。作用域,Local Storage、Session Storage 和 Cookie 都遵循同源策略。但 Session Storage 特别的一点在于,即便是相同域名下的两个页面,只要它们不在同一个浏览器窗口中打开,那么它们的 Session Storage 内容便无法共享(不同tab页面不能共享)。
 
使用CDN缓存
- CDN 的核心点有两个,一个是缓存,一个是回源(缓存过期向上层服务器请求资源)。
 - CDN 往往被用来存放静态资源。“静态资源”,就是像JS、CSS、图片等不需要业务服务器进行计算即得的资源。
服务端渲染
浏览器运行机制
 - 渲染过程:首先基于 HTML 构建一个 DOM 树,这棵 DOM 树与 CSS 解释器解析出的 CSSOM 相结合,就有了布局渲染树。最后浏览器以布局渲染树为蓝本,去计算布局并绘制图像,我们页面的初次渲染就大功告成了。
 
- CSS 优化
 
- CSS 选择符是从右到左进行匹配的。
 - 避免使用通配符,只对需要用到的元素进行选择。
 - 关注可以通过继承实现的属性,避免重复匹配重复定义。
 - 少用标签选择器。如果可以,用类选择器替代。
 - 减少选择器嵌套。
 
- CSS与JS加载顺序优化
 
- CSS 是阻塞的资源。浏览器在构建 CSSOM 的过程中,不会渲染任何已处理的内容。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间。
 - JS 引擎是独立于渲染引擎存在的。当 HTML 解析器遇到一个 script 标签时,它会暂停渲染过程,将控制权交给 JS 引擎。JS 引擎对内联的 JS 代码会直接执行,对外部 JS 文件还要先获取到脚本、再进行执行。等 JS 引擎运行完毕,浏览器又会把控制权还给渲染引擎,继续 CSSOM 和 DOM 的构建。
 - 通过对JS使用 defer 和 async 来避免不必要的阻塞。
 - async 模式下,JS 不会阻塞浏览器做任何其它的事情。它的加载是异步的,当它加载结束,JS 脚本会立即执行。
 - defer 模式下,JS 的加载是异步的,执行是被推迟的。等整个文档解析完成、DOMContentLoaded 事件即将被触发时,被标记了 defer 的 JS 文件才会开始依次执行。
 - 脚本与 DOM 元素和其它脚本之间的依赖关系不强时,我们会选用 async;当脚本依赖于 DOM 元素和其它脚本的执行结果时,我们会选用 defer。
 
DOM优化
- DOM操作为什么慢:(1)JS 引擎和渲染引擎(浏览器内核)是独立实现的。用 JS 去操作 DOM 时依赖了桥接接口作为“桥梁”。(2)DOM 的修改引发样式的更迭,会触发回流或重绘。
 - 回流(重排):当我们对 DOM 的修改引发了DOM几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)。时
 - 重绘:当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时。
 - 重绘不一定导致回流,回流一定会导致重绘。回流比重绘做的事情更多,带来的开销也更大。
 - 减少DOM操作
(1)使用js变量 (2)使用DocumentFragment(表示一个没有父级文件的最小文档对象,不是真实 DOM 树的一部分,它的变化不会引起 DOM 树的重新渲染的操作(reflow),且不会导致性能等问题。)https://developer.mozilla.org/zh-CN/docs/Web/API/DocumentFragment 
1  | let container = document.getElementById('container')  | 
Event Loop 与异步更新
回流与重绘
- 触发回流:(1)几何属性有 width、height、padding、margin、left、top、border (2)节点的增减、移动等操作。(3)获取一些也定属性的值(需要即时计算),offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight
 - (1)避免回流与重绘(用js变量将缓存属性值)(2)避免逐条改变样式(通过修改class修改style)(3)将DOM离线,设置display: none,之后再操作
 - Flush对列
 
- 浏览器会缓存flush对列,优化Layout和Paint。
 
Lazy-Load优化首屏体验
- 监听屏幕加载页面
 
节流(throttle)与防抖(debounce)
性能监控
- chrome Performance面板
 - LightHouse